/* eslint import/prefer-default-export: off */
import { URL } from 'url';
import { dialog } from 'electron';
import fs from 'fs';
import * as XLSX from 'xlsx';
import path from 'path';

export function resolveHtmlPath(htmlFileName: string) {
  if (process.env.NODE_ENV === 'development') {
    const port = process.env.PORT || 1212;
    const url = new URL(`http://localhost:${port}`);
    url.pathname = htmlFileName;
    return url.href;
  }
  return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`;
}

export const decodeFile = (book: XLSX.WorkBook, key: string) => {
  const ppMap: Record<string, unknown[]> = {};
  const originJson: Record<string, unknown> = {};
  const head: string[] = [];
  book.SheetNames.forEach((name) => {
    const sheet = book.Sheets[name];

    const json: Array<Array<string>> = XLSX.utils.sheet_to_json(sheet, {
      raw: true,
      header: 1,
    });

    originJson[name] = json;

    const max = json.reduce((p, n) => {
      return Math.max(p, n.length);
    }, 0);

    let h = 0;
    while (h <= max) {
      head[h] = json[0][h];
      h += 1;
    }
    let at = -1; // 找到解析的ColIndex
    for (let j = 0; j < head.length; j += 1) {
      if (head[j].includes(key)) {
        at = j;
        break;
      }
    }
    if (at === -1) return;
    for (let i = 1; i < json.length; i += 1) {
      const ppName = json[i][at];
      if (!ppName || ppName === ' ') {
        // eslint-disable-next-line no-continue
        continue;
      } else if (ppMap[ppName]) {
        ppMap[ppName].push(json[i]);
      } else {
        ppMap[ppName] = [json[i]];
      }
    }
  });
  return { head, data: ppMap, json: originJson };
};
// 读取文件
const readByFs = (filePath: string): Promise<Buffer> => {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, (err, data) => {
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
};
// 打开附件
export const openFile = async (): Promise<{
  filePath: string;
  book: XLSX.WorkBook;
}> => {
  try {
    const {
      filePaths: [filePath],
    } = await dialog.showOpenDialog({
      filters: [
        {
          name: 'EXCEL',
          extensions: ['xlsx'],
        },
      ],

      properties: ['openFile'],
    });
    if (filePath) {
      const data = await readByFs(filePath);
      const book = XLSX.read(data.buffer, { cellDates: true });
      return await Promise.resolve({ filePath, book });
    }
    return Promise.reject(JSON.stringify({ type: 1, message: '未选择文件' }));
  } catch (error) {
    return Promise.reject(
      JSON.stringify({ type: 2, message: '打开附件失败', info: error }),
    );
  }
};
// 写入文件
const writeByFs = (filePath: string, b: Buffer): Promise<void> => {
  return new Promise((resolve, reject) => {
    fs.writeFile(filePath, b, (err) => {
      if (err) {
        reject(JSON.stringify({ type: 3, message: '写入文件失败', info: err }));
      } else {
        resolve();
      }
    });
  });
};

// 导出EXCEl文件
export const creatExcel = async (arg: { name: string; data: any }) => {
  try {
    const fileName = `${arg.name}.xlsx`;
    const wb = XLSX.utils.book_new();
    const ws = XLSX.utils.json_to_sheet(arg.data);
    XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
    const { filePath } = await dialog
      .showSaveDialog({
        defaultPath: fileName,
        properties: ['createDirectory'],
      })
      .catch(() => {
        throw new Error('cancel');
      });
    if (filePath) {
      const b = XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' });
      await writeByFs(filePath, b);
      return await Promise.resolve(filePath);
    }
    return await Promise.reject(
      JSON.stringify({ type: 4, message: '取消创建' }),
    );
  } catch (error) {
    return Promise.reject(error);
  }
};
// 创建文件
export const creatExcelAll = async (arg: { name: string; data: any }[]) => {
  try {
    const books: any[] = [];
    arg.forEach(({ name, data }) => {
      const fileName = `${name}.xlsx`;
      const wb = XLSX.utils.book_new();
      const ws = XLSX.utils.json_to_sheet(data);
      XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
      books.push({ fileName, wb });
    });
    const { filePaths } = await dialog
      .showOpenDialog({
        properties: ['createDirectory', 'openDirectory'],
      })
      .catch(() => {
        throw new Error('cancel');
      });

    if (filePaths.length) {
      const taks: Array<Promise<any>> = [];
      for (let i = 0; i < books.length; i += 1) {
        const item = books[i];
        const b = XLSX.write(item.wb, { type: 'buffer', bookType: 'xlsx' });
        taks.push(writeByFs(`${filePaths[0]}/${item.fileName}`, b));
      }
      await Promise.all(taks);
      return await Promise.resolve(filePaths[0]);
    }
    return Promise.reject(JSON.stringify({ type: 5, message: '取消创建' }));
  } catch (error) {
    return Promise.reject(error);
  }
};
// 调用js解析
export const decodeByJavascript = async (params: {
  data: Record<string, any[][]>;
}) => {
  try {
    const { data } = params;
    const wb = XLSX.utils.book_new();

    const fileName = `${new Date().getTime()}.xlsx`;

    Object.keys(data).forEach((key) => {
      const ws = XLSX.utils.json_to_sheet(data[key]);
      XLSX.utils.book_append_sheet(wb, ws, key);
    });

    const { filePath } = await dialog
      .showSaveDialog({
        defaultPath: fileName,
        properties: ['createDirectory'],
      })
      .catch(() => {
        throw new Error('cancel');
      });
    if (filePath) {
      const b = XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' });
      await writeByFs(filePath, b);
      return await Promise.resolve(filePath);
    }
    return await Promise.reject(
      JSON.stringify({ type: 4, message: '取消创建' }),
    );
  } catch (error) {
    throw new Error('解析失败 decodeError');
  }
};
